package com.toocms.jinjuhang.ui.cart

import android.app.Application
import android.os.Bundle
import androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableBoolean
import androidx.databinding.ObservableField
import com.toocms.jinjuhang.R
import com.toocms.jinjuhang.BR
import com.toocms.jinjuhang.config.Constants
import com.toocms.jinjuhang.config.Urls
import com.toocms.jinjuhang.config.UserRepository
import com.toocms.jinjuhang.data.cart.CartListData
import com.toocms.jinjuhang.data.cart.GetTotalAmountsData
import com.toocms.jinjuhang.ui.mine.order.confirm.ConfirmOrderFgt
import com.toocms.jinjuhang.widget.view_model.requestData
import com.toocms.tab.base.BaseModel
import com.toocms.tab.base.BaseViewModel
import com.toocms.tab.binding.ItemBinding
import com.toocms.tab.binding.command.BindingAction
import com.toocms.tab.binding.command.BindingCommand
import com.toocms.tab.bus.Messenger
import com.toocms.tab.bus.event.SingleLiveEvent

class CartModel(application: Application) : BaseViewModel<BaseModel>(application) {
    private var p = 1

    val items = ObservableArrayList<CartItemModel>()
    val itemBinding = ItemBinding.of<CartItemModel>(BR.cartItemModel, R.layout.item_cart)

    val selectedCommodityTotalSumObservableField = ObservableField("0.00")
    val isEditObservableBoolean = ObservableBoolean(false)
    val isAllCheckObservableBoolean = ObservableBoolean(false)
    val stopRefreshOrLoadSingleLiveEvent = SingleLiveEvent<Unit>()
    val refreshBindingCommand = BindingCommand<BindingAction>(this::refresh)
    val loadBindingCommand = BindingCommand<BindingAction>(this::load)

    val editClickBindingCommand = BindingCommand<BindingAction>(BindingAction {
        isEditObservableBoolean.set(!isEditObservableBoolean.get())
        if (!isEditObservableBoolean.get()) {
            getTotalAmounts()
        }
    })
    val functionClickBindingCommand = BindingCommand<BindingAction>(BindingAction {
        val selectedCartIds = selectedCartIds()
        if (selectedCartIds.isNullOrEmpty()) {
            showToast(R.string.str_no_selected_cart_commodity_hint)
            return@BindingAction
        }
        if (isEditObservableBoolean.get()) {
            val params = mutableMapOf<String, String?>()
            params["member_id"] = UserRepository.user.member_id
            params["cart_ids"] = selectedCartIds
            requestData(
                Urls.Cart.DEL_FROM_CART,
                params,
                resultClass = String::class.java,
                result = {
                    showToast(it)
                    refresh()
                })
        } else {
            val params = Bundle()
            params.putString(Constants.BundleKey.KEY_CART_IDS, selectedCartIds)
            startFragment(ConfirmOrderFgt::class.java, params)
        }
    })
    val allCheckClickBindingCommand = BindingCommand<BindingAction>(BindingAction {
        val isAllCheck = if (items.isNullOrEmpty()) false else !isAllCheckObservableBoolean.get()
        isAllCheckObservableBoolean.set(isAllCheck)
        items.forEach {
            it.isSelectedObservableBoolean.set(isAllCheck)
        }
        getTotalAmounts()
    })

    init {
        initializeMessenger()
        refresh()
    }

    private fun initializeMessenger() {
        Messenger.getDefault().register(this, Constants.MessengerToken.TOKEN_REFRESH_CART) {
            refresh()
        }
    }


    private fun refresh() {
        p = 1
        cartList(p)
    }

    private fun load() {
        p++
        cartList(p)
    }

    private fun selectedCartIds(): String {
        val result = StringBuilder()
        items.forEach {
            it.item.get()?.apply {
                if (!it.isSelectedObservableBoolean.get()) return@forEach
                if (!result.isNullOrEmpty()) result.append(Constants.Extra.DECOLLATOR_DEFAULT)
                result.append(cart_id)
            }
        }
        return result.toString()
    }

    fun refreshAllCheckStatus() {
        var isAllCheck = true
        items.forEach {
            if (!it.isSelectedObservableBoolean.get()) isAllCheck = false
        }
        if (items.isNullOrEmpty()) isAllCheck = false
        isAllCheckObservableBoolean.set(isAllCheck)
    }

    //--------------------------------------API-----------------------------------------------------

    private fun cartList(p: Int) {
        val params = mutableMapOf<String, String?>()
        params["member_id"] = UserRepository.user.member_id
        params["p"] = p.toString()
        requestData(Urls.Cart.CART_LIST, params, resultClass = CartListData::class.java, result = {
            if (1 == p) items.clear()
            it.list?.forEach {
                items += CartItemModel(this, ObservableField(it))
            }
        }, finish = {
            stopRefreshOrLoadSingleLiveEvent.call()
        })
    }

    fun getTotalAmounts() {
        val params = mutableMapOf<String, String?>()
        params["member_id"] = UserRepository.user.member_id
        params["cart_ids"] = selectedCartIds()
        requestData(
            Urls.Cart.GET_TOTAL_AMOUNTS,
            params,
            resultClass = GetTotalAmountsData::class.java,
            result = {
                selectedCommodityTotalSumObservableField.set(it.price_total ?: "0.00")
            })
    }

}